package com.dingwen.minser.controller;

import ch.qos.logback.core.util.FileUtil;
import com.dingwen.minser.exception.ServiceException;
import com.dingwen.minser.result.Result;
import com.dingwen.minser.result.ResultGenerator;
import com.dingwen.minsta.service.FileService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * entrance controller
 *
 * @author dingwen
 * 2021.05.28 14:07
 */
@RestController
@RequestMapping("/minio")
@Api(value = "minio 服务", tags = "minio")
public class EntranceController {
    /**
     * 文件服务
     */
    private final FileService fileService;

    @Autowired
    EntranceController(FileService fileService) {
        this.fileService = fileService;
    }

    /**
     * 创建bucket
     *
     * @return {@link Result}
     */
    @ApiOperation("创建bucket")
    @ApiImplicitParam(value = "存储桶名称", name = "bucketName", required = true)
    @PostMapping("/bucket/add")
    public Result add(@RequestParam("bucketName") String bucketName) {
        boolean flag = fileService.createBucket(bucketName);
        return flag ? ResultGenerator.genOkResult(bucketName + "创建成功")
                : ResultGenerator.genFailureResult(bucketName + "创建失败");
    }


    /**
     * 删除
     *
     * @param bucketName bucket名称
     * @return {@link Result}
     */
    @ApiOperation("删除bucket")
    @ApiImplicitParam(value = "存储桶名称", name = "bucketName", required = true)
    @DeleteMapping("/bucket/remove")
    public Result remove(@RequestParam("bucketName") String bucketName) {
        boolean flag = fileService.removeBucket(bucketName);
        return flag ? ResultGenerator.genOkResult(bucketName + "删除成功")
                : ResultGenerator.genFailureResult(bucketName + "删除失败");
    }


    /**
     * 上传
     *
     * @param multipartFile       文件
     * @param bucketName          bucket名称
     * @param destinationFileName 目标文件的名字
     * @return {@link Result}
     */
    @ApiOperation("文件上传")
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(value = "文件", required = true, name = "multipartFile"),
                    @ApiImplicitParam(value = "存储桶名称", required = true, name = "bucketName"),
                    @ApiImplicitParam(value = "目标文件名", required = false, name = "destinationFileName")
            }

    )
    @PostMapping("/file/upload")
    public Result upload(@RequestParam(value = "multipartFile", required = true) MultipartFile multipartFile,
                         @RequestParam(value = "bucketName", required = true) String bucketName,
                         @RequestParam(value = "destinationFileName", required = false) String destinationFileName) {
        try {
            String fileName = null;
            if (!StringUtils.hasText(destinationFileName)
                    || ObjectUtils.isEmpty(destinationFileName)
                    || destinationFileName.equalsIgnoreCase("null")) {
                destinationFileName = multipartFile.getOriginalFilename();
            }
            fileName = fileService.saveFile(bucketName, new ByteArrayInputStream(multipartFile.getBytes()), destinationFileName);
            return StringUtils.hasText(fileName) ? ResultGenerator.genOkResult("文件已成功上传,文件名：" + fileName) :
                    ResultGenerator.genFailureResult("文件上传失败").setCode(Integer.parseInt(HttpStatus.INTERNAL_SERVER_ERROR.name()));
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("文件上传失败:{}", e.getMessage());
        }
    }


    /**
     * 下载
     *
     * @param response   响应
     * @param bucketName bucket名称
     * @param fileName   文件名称
     * @return {@link ResponseEntity<Resource>}
     */

    @ApiOperation("文件下载")
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(value = "存储桶名称", name = "bucketName"),
                    @ApiImplicitParam(value = "文件名称", name = "fileName"),
            }
    )
    @GetMapping("/file/download")
    public ResponseEntity<Resource> download(
            HttpServletResponse response,
            @RequestParam("bucketName") String bucketName,
            @RequestParam("fileName") String fileName
    ) throws UnsupportedEncodingException {
        fileName = fileName.trim();
        response.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE);
        // 文件名中文乱码解决
        response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1"));
        try {
            fileService.write(fileName, bucketName, response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceException("文件下载异常：{}", e.getMessage());
        }
        return null;
    }


    /**
     * 文件删除
     *
     * @param fileName   文件名称
     * @param bucketName bucket名称
     * @return {@link Result}
     */

    @ApiOperation("删除文件")
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(value = "文件名称", name = "fileName"),
                    @ApiImplicitParam(value = "存储桶名称", name = "bucketName")
            }
    )
    @DeleteMapping("file/remove")
    public Result remove(@RequestParam("fileName") String fileName, @RequestParam(value = "bucketName", required = false) String bucketName) {
        boolean flag = false;
        if (StringUtils.hasText(bucketName)) {
            flag = fileService.removeFile(bucketName, fileName);
        } else {
            flag = fileService.removeFile(fileName);
        }
        return flag ? ResultGenerator.genOkResult("删除文件成功") : ResultGenerator.genFailureResult("删除文件失败");
    }
}
